<?php

namespace App;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\DB;

class Member extends Model
{
    use Notifiable;

    /**
     * 应该被调整为日期的属性
     *
     * @var array
     */
    protected $dates = ['created_at', 'updated_at','check_at'];


    public function level() {
        return $this->belongsTo(Level::class);
    }

    public function parent() {
        return $this->belongsTo(Member::class,'pid');
    }

    public function children() {
        return $this->hasMany(Member::class,'pid','id');
    }

    public function addresses() {
        return $this->hasMany(Address::class);
    }

    public function orders() {
        return $this->hasMany(Order::class);
    }


    public function accounts() {
        return $this->hasMany(Account::class,'mid');
    }

    public function moneys() {
        return $this->hasMany(Money::class);
    }

    public function creditCards() {
        return $this->hasMany(CreditCard::class);
    }


    public function getPriceAttribute() {
        return $this->level->price;
    }


    public function getBalanceAttribute() {
        return $this->accounts()->sum('amount');
    }

    public function getMoneyAttribute() {
        return $this->moneys()->sum('amount');
    }

    /**
     * 得到总代销售业绩
     */
    public function getAgentSales($month) {
        $agent_ids = $this->children()
            ->where('level_id',$this->level_id)
            ->pluck('id')
            ->toArray();

        //加入自己
        $agent_ids[]=$this->id;
        $check_at = $this->check_at;
        $date_end = $this->check_at->addDays($month*30);

        //销量
//        $sale_num = Order::whereIn('member_id',$agent_ids)
//            ->where('status','>=',1)
//            ->where('paid_at','>=',$check_at)
//            ->details()->sum('num');

        $sale_num = OrderDetail::whereIn('order_id',function($qy2) use($agent_ids,$check_at,$date_end)  {
                $qy2->select('id')
                ->from('orders')
                ->whereIn('member_id',$agent_ids)
                ->where('status','>=',1)
                ->where('paid_at','>=',$check_at)
                ->where('paid_at','<=',$date_end);
            })
            ->sum('num');
        return $sale_num;
    }


    /**
     * 总代是否通过考核
     */
    public function agentPassedCheck() {
        $param = SysParam::find(1001);

        $check_val1 = $param->value;
        $check_val2 = $param->value2;
        $sale_num = $this->getAgentSales($check_val1);
        return $sale_num>=$check_val2;
    }



    /**
     * 总代推荐同级数量
     * @return int
     */
    public function getSameLevelNumAttribute() {
        return $this->children()
            ->where('level_id',$this->level_id)
            ->count();
    }



    /**
     * 判断当前会员是否有能力供货，对于订单$order
     * @param $order
     * @return bool
     */
    public function hasStockByOrder($order) {
        return Stock::hasStockByOrder($this,$order);
    }

    /**
     * 得到最近的上级总代或合伙人
     */
    public function getParentAgent() {
        $path = $this->path;
        $depth = $this->depth;
        $parentZd = Member::whereRaw("'{$path}' like CONCAT(path,',','%') ")
            ->whereIn('level_id',[4,5])
            ->orderBy('depth','desc')
            ->first();
        return $parentZd;
    }


    /**
     * 得到可以供货的上级总代
     * @param $order
     * 0: 上级总代无法供货(公司供货)  obj 可供货的上级总代
     */
    public function getHasStockParentAgent($order) {
        $parentZd = $this->getParentAgent();
        if($parentZd) {
            if($parentZd->hasStockByOrder($order)) {
                return $parentZd;
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    /**
     * 得到上级可供货的会员id
     * 0 表示公司供货  否则 表示会员(上级或上级总代)供货
     * @param $order
     */
    public function getSupplyMember($order,$upgradeLevelId) {
        if(!$order) {
            throw new \Exception('订单不存在！');
        }

        if($this->level_id==4) {
            //总代从公司进货
            return [0,-1];
        } else {
            //如果没有推荐人 或 待升级级别为总代则有公司供货
            if($this->pid==0 || $upgradeLevelId == 4) {
                //无上级推荐人的从公司进货
                return [0,-1];
            } else {
                //如果直接上级
                info('我是：'.$this->level_id.'----上级是：'.$this->parent->level_id);
                $parentLevelId = $this->parent->level_id;
                if($parentLevelId > $this->level_id && $upgradeLevelId<=$parentLevelId) {
                    info('上级级别比我大！');
                    if($this->parent->hasStockByOrder($order)) {
                        info('上级有货！');
                        return [$this->parent,1];
                    } else {
                        info('上级无货！');
                        //判断上级总代是否有货,如果有货返回上级总代 否则返回0 表示公司供货
                        $parentZd = $this->getHasStockParentAgent($order);
                        return [$parentZd,$parentZd?2:0];
                    }
                } else {
                    info('寻找上级总代！');
                    //判断上级总代是否有货
                    $parentZd = $this->getHasStockParentAgent($order);
                    if($parentZd)
                        info('上级总代有货！');
                    else
                        info('上级总代无货，从公司进货！');
                    return [$parentZd,$parentZd?3:0];
                }
             }
        }
    }



    //根据购买数量得到级别（升级或原级别）
    public function getUpgradeLevelByNum($buy_num) {
        if($this->level_id==0) {
            //首次购买
            $level = Level::where('id','<>',5)
                ->whereRaw($buy_num.'>=require_num')
                ->orderBy('id','desc')
                ->first();

            if($level) {
                return $level->id;
            } else {
                return $this->level_id;
            }

        } else {
            //二次消费
            return $this->level_id;
        }
    }




    //得到级别对应的推荐奖
    public function getRePrize($level_id)
    {
        //9-1优惠政策,9月1日前 总代不拿推荐奖
        if($this->level->id==4 && time()<strtotime('2017-09-01 00:00:00')) {
            return 0;
        }

        $prize = DB::table('level_prizes')
            ->where('level_id',$this->level_id)
            ->where('re_level_id',$level_id)
            ->value('prize');
        return $prize?$prize:0;
    }

    public function makeRePrize() {
        if($this->pid) {
            return $this->parent->getRePrize($this->level_id);
        } else {
            return 0;
        }
    }

    //平级奖励
    public function makePPirze($buy_num) {
        //如果存在同级上级 并且 是从总代进货，则上级享有平级奖
        if($this->pid ) {
            if($this->level_id == $this->parent->level_id ) {
                return 10 * $buy_num;
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    //级差奖金(归直接推荐 或 上级有货的总代)
    public function makeDPrize($buyNum,$supplier_id) {
        if($supplier_id>0) {
            $supplier = Member::find($supplier_id);
            if(!$supplier)
                return 0;
            $diff = $this->level->price - $supplier->level->price;
            return $diff * $buyNum;
        } else {
            return 0;
        }
    }


    /**
     * 总代拓展奖
     * 35 15 10
     */
    public function makeAgentPrize($buyNum) {
        $path = $this->path;
        $level_id = $this->level_id;
        $depth = $this->depth;

        $prize_map= [
            1=>35,2=>15,3=>10
        ];
        $data= [];
        $i=1;

        //非总代或者合伙人进货，没有拓展奖
        if($this->level_id != 4 && $this->level_id != 5) {
            return $data;
        }

        $parents = Member::whereRaw("'{$path}' like CONCAT(path,',','%') ")
            ->where('depth','<',$depth)
            ->whereIn('level_id',[4,5])
            ->orderBy('depth','desc')
            ->get();

        foreach ($parents as $item) {
            if($i<=3) {
                $prize = $prize_map[$i];
                $data[] = [
                    'mid' => $item->id,
                    'amount' => $prize * $buyNum
                ];
            } else {
                break;
            }
            $i++;
        }
        return $data;
    }

    /**
     * 合伙人领导奖
     * 10
     * @param $buyNum
     */
    public function makePartnerPrize($buyNum) {

        //如果是总代进货并且直接上级是合伙人，则合伙人享有领导奖
        $parent = $this->parent;
        if($this->level_id==4 && $parent && $parent->level_id==5) {
            return $buyNum*10;
        } else {
            return 0;
        }
    }




    //得到二次进货（购买）金额
    public function getBuyPrice($first_buy,$buy_num) {
        if($first_buy)
            return $this->level->price*$this->level->require_buy_num;
        else
            return $this->level->price*$buy_num;
    }

    //晋级检查
    public function checkUpgrade() {
        //平级直推数量
        $re_tj_cnt = $this->children()->where('level_id','>=',$this->level_id)
            ->count();
        return $re_tj_cnt>=5?true:false;
    }


    //结算所有奖金
    public function settle($firstBuy,$order) {
        if($firstBuy) {
            return $this->settleFirst($order);
        } else {
            return $this->settleSecond($order);
        }
    }

    //首次购买结算
    protected function settleFirst($order) {
        return DB::transaction(function () use($order) {

            //购买数量
            $buyNum = $order->details()->sum('num');
            $amount = $order->total_amount;

            //写入公司收入表
            $acc = new Account();
            $acc->mid = 0;          //公司账户
            $acc->type = 10;
            $acc->title = '会员购买进账';
            $acc->amount = $amount;
            $acc->rel_mid = $this->id;
            $acc->save();


            //平级推荐奖
            $pPrize = $this->makePPirze($buyNum);
            if ($pPrize > 0) {
                //写入奖金表
                $acc = new Account();
                $acc->mid = $this->pid;
                $acc->type = 2;
                $acc->title = '平级奖励';
                $acc->amount = $pPrize;
                $acc->rel_mid = $this->id;
                $acc->save();
            }

            //级差奖金
//            $dPrize = $this->makeDPrize($buyNum,$order->supplier_id);
//            if ($dPrize > 0) {
//                //写入奖金表
//                $acc = new Account();
//                $acc->mid = $order->supplier_id;
//                $acc->type = 3;
//                $acc->title = '级差奖';
//                $acc->amount = $dPrize;
//                $acc->rel_mid = $this->id;
//                $acc->save();
//            }

            //生成总代拓展奖
            $arrAgentPrize = $this->makeAgentPrize($buyNum);
            foreach ($arrAgentPrize as $r) {
                //写入奖金表
                $acc = new Account();
                $acc->mid = $r['mid'];
                $acc->type = 4;
                $acc->title = '总代拓展奖';
                $acc->amount = $r['amount'];
                $acc->rel_mid = $this->id;
                $acc->save();
            }

            //生成合伙人奖领导奖
            $partnerPrize = $this->makePartnerPrize($buyNum);
            if ($partnerPrize > 0) {
                //写入奖金表
                $acc = new Account();
                $acc->mid = $this->pid;
                $acc->type = 5;
                $acc->title = '合伙人领导奖';
                $acc->amount = $partnerPrize;
                $acc->rel_mid = $this->id;
                $acc->save();
            }


            return true;
        });
        return false;
    }

    //二次消费结算
    protected function settleSecond($order) {
        return DB::transaction(function () use($order) {

            //购买数量
            $buyNum = $order->details()->sum('num');
            $amount = $order->total_amount;

            //写入公司收入表
            $acc = new Account();
            $acc->mid = 0;          //公司账户
            $acc->type = 11;
            $acc->title = '会员二次购买进账';
            $acc->amount = $amount;
            $acc->rel_mid = $this->id;
            $acc->save();

            //平级推荐奖
            $pPrize = $this->makePPirze($buyNum);
            if ($pPrize > 0) {
                //写入奖金表
                $acc = new Account();
                $acc->mid = $this->pid;
                $acc->type = 2;
                $acc->title = '平级奖励';
                $acc->amount = $pPrize;
                $acc->rel_mid = $this->id;
                $acc->save();
            }

            //级差奖金
//            $dPrize = $this->makeDPrize($buyNum,$order->supplier_id);
//            if ($dPrize > 0) {
//
//                //写入奖金表
//                $acc = new Account();
//                $acc->mid = $order->supplier_id;
//                $acc->type = 3;
//                $acc->title = '级差奖';
//                $acc->amount = $dPrize;
//                $acc->rel_mid = $this->id;
//                $acc->save();
//            }

            //生成总代拓展奖
            $arrAgentPrize = $this->makeAgentPrize($buyNum);
            foreach ($arrAgentPrize as $r) {
                //写入奖金表
                $acc = new Account();
                $acc->mid = $r['mid'];
                $acc->type = 4;
                $acc->title = '总代拓展奖';
                $acc->amount = $r['amount'];
                $acc->rel_mid = $this->id;
                $acc->save();
            }

            //生成合伙人奖领导奖
            $partnerPrize = $this->makePartnerPrize($buyNum);
            if ($partnerPrize > 0) {
                //写入奖金表
                $acc = new Account();
                $acc->mid = $this->pid;
                $acc->type = 5;
                $acc->title = '合伙人领导奖';
                $acc->amount = $partnerPrize;
                $acc->rel_mid = $this->id;
                $acc->save();
            }



            return true;
        });
        return false;
    }
}
